home *** CD-ROM | disk | FTP | other *** search
/ Sounds Terrific 2 / Sounds Terrific II (1996)(Weird Science)(Disc 1 of 2)[Amiga-PC].iso / archives / amiga / tracker_4_31.lzh / tracker / st_play.c < prev    next >
C/C++ Source or Header  |  1995-05-15  |  12KB  |  489 lines

  1. /* st_play.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: st_play.c,v 4.21 1995/05/15 12:20:09 espie Exp espie $
  6.  * $Log: st_play.c,v $
  7.  * Revision 4.21  1995/05/15  12:20:09  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 4.20  1995/05/11  12:30:46  espie
  11.  * DELAY PATTERN correction.
  12.  *
  13.  * Revision 4.19  1995/03/11  21:41:01  espie
  14.  * Added invert_loop.
  15.  *
  16.  * Revision 4.18  1995/03/04  00:16:21  espie
  17.  * implemented vibrato wave.
  18.  *
  19.  * Revision 4.17  1995/03/03  14:24:21  espie
  20.  * *** empty log message ***
  21.  *
  22.  * Revision 4.16  1995/03/01  15:24:51  espie
  23.  * data width.
  24.  *
  25.  * Revision 4.15  1995/02/21  21:13:16  espie
  26.  * Cleaned up source. Moved minor pieces of code around.
  27.  *
  28.  * Revision 4.14  1995/02/21  17:54:32  espie
  29.  * Internal problem: buggy RCS. Fixed logs.
  30.  *
  31.  * Revision 4.12  1995/02/20  22:53:31  espie
  32.  * Some display updated.
  33.  *
  34.  * Revision 4.11  1995/02/20  22:28:50  espie
  35.  * 8 channels.
  36.  *
  37.  * Revision 4.10  1995/02/20  16:49:58  espie
  38.  * Added funk_glissando
  39.  *
  40.  * Revision 4.9  1995/02/14  04:02:28  espie
  41.  * Suppressed comment.
  42.  *
  43.  * Revision 4.8  1995/02/06  14:50:47  espie
  44.  * Changed sample_info.
  45.  *
  46.  * Revision 4.7  1995/02/01  20:41:45  espie
  47.  * Added color.
  48.  *
  49.  * Revision 4.6  1995/02/01  16:39:04  espie
  50.  * Left/Right channels.
  51.  *
  52.  * Revision 4.0  1994/01/11  17:51:40  espie
  53.  * Use the new UI calls.
  54.  * Use the new pref settings.
  55.  *
  56.  * Revision 1.14  1994/01/09  23:24:37  Espie
  57.  * Last bug fix.
  58.  * Suppressed really outdated code.
  59.  * New names: new_channel_tag_list, release_audio_channel.
  60.  * Some notice to status.
  61.  * Use new pref scheme.
  62.  * Use get_ui
  63.  * Use autoinit feature of display.c
  64.  * discard_buffer forgotten...
  65.  * Handle errors better.
  66.  *
  67.  * Revision 3.18  1993/12/04  16:12:50  espie
  68.  * Lots of changes.
  69.  * New high-level functions.
  70.  * Amiga support.
  71.  * Bug with delay_pattern: can't factorize the check for effect thingy.
  72.  * Reniced verbose output display.
  73.  * Bug fix: now use correct finetune when loading samples/starting notes.
  74.  * Added bg/fg test.
  75.  * General cleanup
  76.  * Added <> operators.
  77.  * Added update frequency on the fly.
  78.  * Added finetune.
  79.  * Protracker commands.
  80.  *
  81.  * Revision 2.19  1992/11/17  17:15:37  espie
  82.  * Added interface using may_getchar(). Still primitive, though.
  83.  * imask, start.
  84.  * Added transpose feature.
  85.  * Added possibility to get back to MONO for the sgi.
  86.  * Added stereo capabilities to the indigo version.
  87.  * Added two level of fault tolerancy.
  88.  * Added some control on the number of replays,
  89.  * and better error recovery.
  90.  */
  91.      
  92. #include "defs.h"
  93. #include "song.h"
  94. #include "channel.h"
  95. #include "extern.h"
  96. #include "tags.h"
  97. #include "prefs.h"
  98.      
  99.  
  100. extern int vibrato_table[3][64];
  101.  
  102. ID("$Id: st_play.c,v 4.21 1995/05/15 12:20:09 espie Exp espie $")
  103.      
  104.  
  105. /* setting up a given note */
  106. void reset_note(ch, note, pitch)
  107. struct channel *ch;
  108. int note;
  109. int pitch;
  110.    {
  111.    ch->pitch = pitch;
  112.    ch->note = note;
  113.    ch->viboffset = 0;
  114.     ch->tremoffset = 0;
  115.    play_note(ch->audio, ch->samp, pitch);
  116.    }
  117.  
  118. /* changing the current pitch (value may be temporary, and so is not stored
  119.  * in channel pitch, for instance vibratos)
  120.  */
  121. void set_current_pitch(ch, pitch)
  122. struct channel *ch;
  123. int pitch;
  124.    {
  125.    set_play_pitch(ch->audio, pitch);
  126.    }
  127.  
  128. /* changing the current volume, storing it in ch->volume
  129.  */
  130. void set_current_volume(ch, volume)
  131. struct channel *ch;
  132. int volume;
  133.    {
  134.    ch->volume = MAX(MIN(volume, MAX_VOLUME), MIN_VOLUME);
  135.    set_play_volume(ch->audio, ch->volume);
  136.    }
  137.  
  138. /* changing the current volume WITHOUT storing it
  139.  */
  140. void set_temp_volume(ch, volume)
  141. struct channel *ch;
  142. int volume;
  143.     {
  144.     volume = MAX(MIN(volume, MAX_VOLUME), MIN_VOLUME);
  145.     set_play_volume(ch->audio, volume);
  146.     }
  147.  
  148. void set_position(ch, pos)
  149. struct channel *ch;
  150. int pos;
  151.    {
  152.    set_play_position(ch->audio, pos);
  153.    }
  154.  
  155. /* init_channel(ch, dummy):
  156.  * setup channel, with initially a dummy sample ready to play, and no note.
  157.  */
  158. LOCAL void init_channel(ch, side)
  159. struct channel *ch;
  160. int side;
  161.    {
  162.     struct tag tags[2];
  163.     tags[0].type = AUDIO_SIDE;
  164.     tags[0].data.scalar = side;
  165.     tags[1].type = TAG_END;
  166.    ch->samp = empty_sample();
  167.    ch->finetune = 0;
  168.    ch->audio = new_channel_tag_list(tags);
  169.    ch->volume = 0; 
  170.    ch->pitch = 0; 
  171.    ch->note = NO_NOTE;
  172.  
  173.       /* we don't setup arpeggio values. */
  174.    ch->viboffset = 0; 
  175.    ch->vibdepth = 0;
  176.    ch->vibrate = 0;
  177.     ch->vibtable = vibrato_table[0];
  178.     ch->resetvib = FALSE;
  179.  
  180.     ch->tremoffset = 0;
  181.     ch->tremdepth = 0;
  182.     ch->tremrate = 0;
  183.     ch->tremtable = vibrato_table[0];
  184.     ch->resettrem = FALSE;
  185.  
  186.    ch->slide = 0; 
  187.  
  188.    ch->pitchgoal = 0; 
  189.    ch->pitchrate = 0;
  190.  
  191.    ch->volumerate = 0;
  192.  
  193.     
  194.     ch->funk_glissando = FALSE;
  195.     ch->start_offset = 0;
  196.    ch->adjust = do_nothing;
  197.         /* initialize loop to no loop, loop start at 0 
  198.          * (needed for don't you want me, for instance) */
  199.     ch->loop_counter = -1;
  200.     ch->loop_note_num = 0;
  201.  
  202.    ch->special = do_nothing;
  203.     ch->invert_speed = 0;
  204.     ch->invert_offset = 0;
  205.     ch->invert_position = 0;
  206.    }
  207.  
  208.  
  209.  
  210. LOCAL int VSYNC;        /* base number of sample to output */
  211. LOCAL void (*eval[NUMBER_EFFECTS]) P((struct automaton *a, struct channel *ch));
  212.                             /* the effect table */
  213. LOCAL int oversample;   /* oversample value */
  214. LOCAL int frequency;    /* output frequency */
  215.  
  216. LOCAL struct channel chan[MAX_TRACKS];
  217.                     /* every channel */
  218.  
  219. LOCAL int ntracks;        /* number of tracks of the current song */
  220. LOCAL struct sample_info **voices;
  221.  
  222. LOCAL struct automaton a;
  223.  
  224.  
  225. void init_player(o, f)
  226. int o, f;
  227.    {
  228.    oversample = o;
  229.    frequency = f;
  230.    init_tables(o, f);
  231.    init_effects(eval);
  232.    }
  233.  
  234. LOCAL void setup_effect(ch, a, e)
  235. struct channel *ch;
  236. struct automaton *a;
  237. struct event *e;
  238.    {
  239.    int samp, cmd;
  240.  
  241.       /* retrieves all the parameters */
  242.    samp = e->sample_number;
  243.  
  244.       /* load new instrument */
  245.    if (samp)  
  246.       {  /* note that we can change sample in the middle of a note. This 
  247.              * is a *feature*, not a bug (see made). Precisely: the sample 
  248.              * change will be taken into account for the next note, BUT the 
  249.              * volume change takes effect immediately.
  250.           */
  251.       ch->samp = voices[samp];
  252.         ch->finetune = voices[samp]->finetune;
  253.         if ((1L<<samp) & get_pref_scalar(PREF_IMASK))
  254.             ch->samp = empty_sample();
  255.         set_current_volume(ch, voices[samp]->volume);
  256.       }
  257.  
  258.    a->note = e->note;
  259.    if (a->note != NO_NOTE)
  260.       a->pitch = pitch_table[a->note][ch->finetune];
  261.    else
  262.       a->pitch = e->pitch;
  263.    cmd = e->effect;
  264.    a->para = e->parameters;
  265.  
  266.    if (a->pitch >= REAL_MAX_PITCH)
  267.       {
  268.       char buffer[60];
  269.  
  270.       sprintf(buffer,"Pitch out of bounds %d", a->pitch);
  271.       status(buffer);
  272.       a->pitch = 0;
  273.       error = FAULT;
  274.       }
  275.  
  276.       /* check for a new note: portamento
  277.        * is the special case where we do not restart
  278.        * the note.
  279.        */
  280.    if (a->pitch && cmd != EFF_PORTA && cmd != EFF_PORTASLIDE)
  281.       reset_note(ch, a->note, a->pitch);
  282.    ch->adjust = do_nothing;
  283.       /* do effects */
  284.    (eval[cmd])(a, ch);
  285.    }
  286.  
  287.  
  288. LOCAL void adjust_sync(ofreq, tempo)
  289. int ofreq, tempo;
  290.    {
  291.    VSYNC = ofreq * NORMAL_FINESPEED / tempo;
  292.    }
  293.  
  294. LOCAL void dump_events(a)
  295. struct automaton *a;
  296.     {
  297.         /* display the output in a reasonable order:
  298.          * LEFT1 LEFT2 || RIGHT1 RIGHT 2
  299.          */
  300.     dump_event(chan, &(a->pattern->e[0][a->note_num]));
  301.     dump_event(chan+3, &(a->pattern->e[3][a->note_num]));
  302.     if (ntracks > 4)
  303.         dump_event(chan+4, &(a->pattern->e[4][a->note_num]));
  304.     if (ntracks > 7)
  305.         dump_event(chan+7, &(a->pattern->e[7][a->note_num]));
  306.     dump_delimiter();
  307.     dump_event(chan+1, &(a->pattern->e[1][a->note_num]));
  308.     dump_event(chan+2, &(a->pattern->e[2][a->note_num]));
  309.     if (ntracks > 5)
  310.         dump_event(chan+5, &(a->pattern->e[5][a->note_num]));
  311.     if (ntracks > 6)
  312.         dump_event(chan+6, &(a->pattern->e[6][a->note_num]));
  313.     dump_event(0, 0);
  314.     }
  315.  
  316.  
  317. LOCAL void play_once(a)
  318. struct automaton *a;
  319.    {
  320.    int channel;
  321.  
  322.    if (a->counter == 0)
  323.       {    /* do new effects only if not in delay mode */
  324.       if (a->delay_counter == 0) 
  325.          {
  326.          for (channel = 0; channel < ntracks; channel++)
  327.             /* setup effects */
  328.             setup_effect(chan + channel, a,
  329.                &(a->pattern->e[channel][a->note_num]));
  330.               if (get_pref_scalar(PREF_SHOW))
  331.                  dump_events(a);
  332.          }
  333.       }
  334.    else
  335.       for (channel = 0; channel < ntracks; channel++)
  336.             {
  337.          /* do the effects */
  338.            (chan[channel].special)(chan + channel);
  339.          (chan[channel].adjust)(chan + channel);
  340.             }
  341.  
  342.       /* advance player for the next tick */
  343.    next_tick(a);
  344.       /* actually output samples */
  345.    resample(oversample, VSYNC / a->finespeed);
  346.    }
  347.  
  348. LOCAL struct tag pres[2];
  349.  
  350.  
  351. LOCAL void init_channels()
  352.     {
  353.    release_audio_channels();
  354.  
  355.     init_channel(chan, LEFT_SIDE);
  356.     init_channel(chan + 1, RIGHT_SIDE);
  357.     init_channel(chan + 2, RIGHT_SIDE);
  358.     init_channel(chan + 3, LEFT_SIDE);
  359.     if (ntracks > 4)
  360.         {
  361.         init_channel(chan + 4, LEFT_SIDE);
  362.         init_channel(chan + 5, RIGHT_SIDE);
  363.         }
  364.     if (ntracks > 6)
  365.         {
  366.         init_channel(chan + 6, RIGHT_SIDE);
  367.         init_channel(chan + 7, LEFT_SIDE);
  368.         }
  369.     }
  370.  
  371. struct tag *play_song(song, start)
  372. struct song *song;
  373. int start;
  374.    {
  375.    int tempo;
  376.    int countdown;      /* keep playing the tune or not */
  377.  
  378.    song_title(song->title);
  379.    pres[1].type = TAG_END;
  380.    
  381.     ntracks = song->ntracks;
  382.     set_number_tracks(ntracks);
  383.    tempo = get_pref_scalar(PREF_SPEED);
  384.  
  385.    adjust_sync(frequency, tempo);
  386.     /* a repeats of 0 is infinite replays */
  387.    
  388.    countdown = get_pref_scalar(PREF_REPEATS);
  389.    if (countdown == 0)
  390.       countdown = 50000;   /* ridiculously huge number */
  391.  
  392.    voices = song->samples; 
  393.  
  394.    init_automaton(&a, song, start);
  395.  
  396.     init_channels();
  397.  
  398.     set_data_width(song->side_width, song->max_sample_width);
  399.  
  400.    while(countdown)
  401.       {
  402.       struct tag *result;
  403.       
  404.       play_once(&a);
  405.       result = get_ui();
  406.       while(result = get_tag(result))
  407.          {
  408.          switch(result->type)
  409.             {  
  410.          case UI_LOAD_SONG:
  411.             if (!result->data.pointer)
  412.                break;
  413.          case UI_NEXT_SONG:
  414.          case UI_PREVIOUS_SONG:
  415.             discard_buffer();
  416.             pres[0].type = result->type;
  417.             pres[0].data = result->data;
  418.             return pres;
  419.          case UI_QUIT:
  420.             discard_buffer();
  421.             end_all(0);
  422.             /* NOTREACHED */
  423.          case UI_SET_BPM:
  424.             tempo = result->data.scalar;
  425.             adjust_sync(frequency, tempo);
  426.             break;
  427.          case UI_RESTART:
  428.             discard_buffer();
  429.             init_automaton(&a, song, start);
  430.                 init_channels();
  431.             break;
  432.          case UI_JUMP_TO_PATTERN:
  433.             if (result->data.scalar >= 0 && 
  434.                         result->data.scalar < a.info->length)
  435.                {
  436.                discard_buffer();
  437.                init_automaton(&a, song, result->data.scalar);
  438.                }
  439.             break;
  440.             /*
  441.          case ' ':
  442.             while (may_getchar() == EOF)
  443.                ;
  444.             break;
  445.              */
  446.          default:
  447.             break;
  448.             }
  449.          result++;
  450.          }
  451.  
  452.       {
  453.       int new_freq;
  454.       if (new_freq = update_frequency())
  455.          {
  456.          frequency = new_freq;
  457.          adjust_sync(frequency, tempo);
  458.          init_tables(oversample, frequency);
  459.          }
  460.       }
  461.  
  462.       switch(error)
  463.          {
  464.       case NONE:
  465.          break;
  466.       case ENDED:
  467.          countdown--;
  468.          break;
  469.       case SAMPLE_FAULT:
  470.       case FAULT:
  471.       case PREVIOUS_SONG:
  472.       case NEXT_SONG:
  473.       case UNRECOVERABLE:
  474.          if ( (error == SAMPLE_FAULT && get_pref_scalar(PREF_TOLERATE))
  475.             ||(error == FAULT && get_pref_scalar(PREF_TOLERATE) > 1) )
  476.             break;
  477.          pres[0].type = PLAY_ERROR;
  478.          pres[0].data.scalar = error;
  479.          return pres;
  480.       default:
  481.          break;
  482.          }
  483.          error = NONE;
  484.       }
  485.    pres[0].type = PLAY_ENDED;
  486.    return pres;
  487.    }
  488.  
  489.